package com.ehotting.edsta.mqbd.signal.netty.call;

import com.alibaba.fastjson.JSON;
import com.ehotting.eaf.core.DateHelper;
import com.ehotting.eaf.core.utils.AssertUtils;
import com.ehotting.eaf.netty.client.TcpClient;
import com.ehotting.eaf.netty.domain.DataAble;
import com.ehotting.edsta.mqbd.api.enums.SysModuleEnum;
import com.ehotting.edsta.mqbd.signal.api.SignalActionConstants;
import com.ehotting.edsta.mqbd.signal.api.bean.MqSignalTcpData;
import com.ehotting.edsta.mqbd.signal.api.domain.netty.CallSimulateRequest;
import com.ehotting.edsta.mqbd.signal.api.domain.netty.LogPushRequest;
import com.ehotting.edsta.mqbd.signal.api.domain.netty.StopSimulateRequest;
import com.ehotting.edsta.mqbd.signal.netty.handler.SiTcpMultiClient;
import com.ehotting.edsta.mqbd.signal.netty.handler.SignalAnalysisTcpClient;
import com.ehotting.edsta.mqbd.signal.netty.service.SiMsgStateHandler;
import com.ehotting.mqbd.api.MQDBConstants;
import com.ehotting.mqbd.api.MqActionConstants;
import com.ehotting.mqbd.api.MqDataStateConstants;
import com.ehotting.mqbd.api.bean.MQDataAble;
import com.ehotting.mqbd.api.bean.MsgStateBean;
import com.ehotting.mqbd.api.bean.solver.SolverInfoBean;
import com.ehotting.mqbd.api.bean.solver.SolverStateBean;
import com.ehotting.mqbd.api.enums.MsgStateEnum;
import com.ehotting.mqbd.api.enums.TopicEnum;
import com.ehotting.mqbd.api.exception.CallException;
import com.ehotting.mqbd.api.exception.SuspendCurrentQueueMomentException;
import com.ehotting.mqbd.api.exception.TcpException;
import com.ehotting.mqbd.core.call.CallerAbstract;
import com.ehotting.mqbd.core.manager.AgentLinkManager;
import com.ehotting.mqbd.core.manager.MsgStateManager;
import com.ehotting.mqbd.core.sync.TcpClientMapHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.Date;

public class MqSignalTcpCaller  extends CallerAbstract {

    public static Logger logger = LoggerFactory.getLogger(MqSignalTcpCaller.class);

    @Autowired
    private SiTcpMultiClient siTcpMultiClient;
    @Autowired
    private AgentLinkManager agentLinkManager;
    @Autowired
    private SiMsgStateHandler siMsgStateHandler;

    @Override
    public void doAction(SolverStateBean serverState, MQDataAble data) {
        logger.info("Start doAction");

        MqSignalTcpData tcpData = (MqSignalTcpData) data;

        siMsgStateHandler.handleCancel(tcpData);

        DataAble response =  sendPkg(tcpData.getRequest(),data.getModule(),data.getAgentId(),serverState.getSolverInfo());
        if(response!=null) {
            tcpData.setResponse(response);
        }

        logger.info("Finish doAction");
    }

    @Override
    public void validData(MQDataAble data) {
        AssertUtils.isTrue(data instanceof MqSignalTcpData,
                new CallException(MqDataStateConstants.CONVERT_ERROR,"data not instanceof MQTcpData"));

        if(data.getRequest() instanceof CallSimulateRequest){
            String clientIp = agentLinkManager.getClientIpByAgentId(data.getAgentId());
            AssertUtils.notNull(clientIp,
                    new SuspendCurrentQueueMomentException(MqDataStateConstants.CLIENT_OFFLINE,
                    "clientIp offline by agentId["+data.getAgentId()+"],break."));
        }
    }


    public DataAble sendPkg(DataAble tcpData,String module, String agentId, SolverInfoBean solverInfo)  {
        logger.info("agentId:{},ip:{},port:{}",agentId, solverInfo.getIp(),solverInfo.getPort());
        SignalAnalysisTcpClient idleTcpClient = (SignalAnalysisTcpClient) siTcpMultiClient.getByAgentIdAndIp(module,agentId,solverInfo);

        if(tcpData instanceof CallSimulateRequest ){
            AssertUtils.notNull(idleTcpClient,new SuspendCurrentQueueMomentException(MqDataStateConstants.TCP_NULL,"连接实例为空"));
        }else{
            AssertUtils.notNull(idleTcpClient,new TcpException(MqDataStateConstants.TCP_NULL,"连接实例为空"));
        }
        DataAble result = idleTcpClient.request(tcpData, 10, true);
        logger.info("sendPkg result:{}", JSON.toJSONString(result));
        return result;
    }


    @Override
    public MQDataAble genMqQueueData(String module,long queueIndex,MsgStateBean msgState,SolverStateBean solverState){
        MqSignalTcpData data = MqSignalTcpData.create(TopicEnum.CONCURRENCY,
                null,
                MQDBConstants.DISPATCHER_HOST,
                msgState.getAgentId(),
                SysModuleEnum.SIGNAL_ANALYSIS.getCode(),"");

        String time = "["+ DateHelper.toSeparatorStringyyyyMMddHHmmss(new Date())+"]";

        Long userId = agentLinkManager.getUserId(msgState.getAgentId());
        Long mainProjectId = agentLinkManager.getProjectId(msgState.getAgentId());
        String msg = time+"信号完整性分析[编号:"+mainProjectId+"]，当前排队为第 "+queueIndex+" 位";

        logger.info("queueIndex:{}",queueIndex);
        if(queueIndex == 0){
            msg = time+"信号完整性分析[编号:"+mainProjectId+"]排队已到，求解器为："+solverState.getSolverInfo().getIp()+"，开始求解";
        }

        if(msgState!=null && msgState.getState()== MsgStateEnum.SOLVING){
            msg = time+"任务"+mainProjectId+"正在求解中，求解器为："+solverState.getSolverInfo().getIp();
        }

        logger.info("msg:{}.",msg);
        LogPushRequest logPushRequest = new LogPushRequest(userId, mainProjectId,msg);
        data.setResponse(logPushRequest);
        return data;
    }

    @Override
    public String getModuleName() {
        return null;
    }
}